/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.libermundi.theorcs.chronicles.services.impl;

import java.util.List;

import org.libermundi.theorcs.chronicles.dao.PersonaDao;
import org.libermundi.theorcs.chronicles.model.Chronicle;
import org.libermundi.theorcs.chronicles.model.Faction;
import org.libermundi.theorcs.chronicles.model.Persona;
import org.libermundi.theorcs.chronicles.model.sheet.Sheet;
import org.libermundi.theorcs.chronicles.model.sheet.SheetPage;
import org.libermundi.theorcs.chronicles.services.ChronicleManager;
import org.libermundi.theorcs.chronicles.services.PersonaManager;
import org.libermundi.theorcs.core.services.impl.AbstractManagerImpl;
import org.libermundi.theorcs.security.model.User;
import org.libermundi.theorcs.security.services.SecurityManager;
import org.libermundi.theorcs.security.services.UserManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service(PersonaManager.SERVICE_ID)
@Transactional(rollbackFor = Exception.class, propagation=Propagation.REQUIRED)
public class PersonaManagerImpl extends AbstractManagerImpl<Persona,Long> implements PersonaManager {
	private static final Logger logger = LoggerFactory.getLogger(PersonaManagerImpl.class);
	
	@Autowired
	private UserManager _userManager;

	@Autowired
	private ChronicleManager _chronicleManager;
	
	@Autowired
	private SecurityManager _securityServices;
	
	@Autowired
	public PersonaManagerImpl(PersonaDao personaDao) {
		super();
		setDao(personaDao);
	}

	@Override
	public void initialize() {
		if(getAllCount() == 0L) {
			logger.debug("Initializing Persona");
			
			Chronicle c = _chronicleManager.loadLast();
			
			assert(c != null);
			
			User admin = _userManager.getUserByUsername("admin");
			User user1 = _userManager.getUserByUsername("user1");
			User user2 = _userManager.getUserByUsername("user2");
			
			Faction f0 = c.getFactions().first();
			Faction f1 = c.getFactions().last();
			
			_securityServices.grantReadAcl(user1, c);
			_securityServices.grantReadAcl(user2, c);
			
			Persona p0 = new Persona();
				p0.setName("*MJ");
				p0.setChronicle(c);
				p0.setPlayer(admin);
				p0.setSheet(buildEmptySheet());
				p0.getFactions().add(f0);
				p0.setDefaultFaction(f0);
			
			Persona p1 = new Persona();
				p1.setName("Harvey Walters");
				p1.setChronicle(c);
				p1.setPlayer(user1);
				p1.setSheet(buildEmptySheet());
				p1.getFactions().add(f0);
				p1.getFactions().add(f1);
				p1.setDefaultFaction(f0);
			
			Persona p2 = new Persona();
				p2.setName("John Rambo");
				p2.setChronicle(c);
				p2.setPlayer(user1);
				p2.setSheet(buildEmptySheet());
				p2.getFactions().add(f0);
				p2.setDefaultFaction(f0);
			
			Persona p3 = new Persona();
				p3.setName("Space Ninja");
				p3.setChronicle(c);
				p3.setPlayer(user2);
				p3.setSheet(buildEmptySheet());
				p3.getFactions().add(f1);
				p3.setDefaultFaction(f1);
			
			save(p0);
			save(p1);
			save(p2);
			save(p3);
			
		}
	}

	@Override
	public Sheet buildEmptySheet() {
		Sheet emptySheet = new Sheet();
		SheetPage page0 = new SheetPage();
		page0.serializePage();
		emptySheet.addPage(page0);
		return emptySheet;
	}

	@Override
	public List<Persona> getChroniclePersonas(Chronicle chronicle) {
		return getDao().getChroniclePersonas(chronicle);
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.chronicles.services.PersonaManager#getAllPersona(org.libermundi.theorcs.security.model.User, org.libermundi.theorcs.chronicles.model.Chronicle)
	 */
	@Override
	public List<Persona> getAllPersona(User user, Chronicle chronicle) {
		return getDao().getAllPersona(user, chronicle);
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.chronicles.services.PersonaManager#getDefaultPersona(org.libermundi.theorcs.security.model.User, org.libermundi.theorcs.chronicles.model.Chronicle)
	 */
	@Override
	public Persona getDefaultPersona(User user, Chronicle chronicle) {
		List<Persona> allPerso = getAllPersona(user, chronicle);
		Persona firstPerso = allPerso.get(0); //By default the first Perso of the list is the default one
		for (Persona persona : allPerso) {
			if(persona.isDefaultPerso()){
				return persona;
			}
		}
		return firstPerso;
	}

	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.core.services.impl.AbstractManagerImpl#getDao()
	 */
	@Override
	public PersonaDao getDao() {
		return (PersonaDao)super.getDao();
	}
}
